home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / graphics / gnuplot / term / post.trm < prev    next >
Text File  |  1993-09-15  |  11KB  |  430 lines

  1. /*
  2.  * $Id: post.trm%v 3.50 1993/07/09 05:35:24 woo Exp $
  3.  */
  4.  
  5. /* GNUPLOT - post.trm */
  6. /*
  7.  * Copyright (C) 1990 - 1993   
  8.  *
  9.  * Permission to use, copy, and distribute this software and its
  10.  * documentation for any purpose with or without fee is hereby granted, 
  11.  * provided that the above copyright notice appear in all copies and 
  12.  * that both that copyright notice and this permission notice appear 
  13.  * in supporting documentation.
  14.  *
  15.  * Permission to modify the software is granted, but not the right to
  16.  * distribute the modified code.  Modifications are to be distributed 
  17.  * as patches to released version.
  18.  *  
  19.  * This software  is provided "as is" without express or implied warranty.
  20.  * 
  21.  * This file is included by ../term.c.
  22.  *
  23.  * This terminal driver supports:
  24.  *     postscript
  25.  *
  26.  * AUTHORS
  27.  *  Russell Lang
  28.  * 
  29.  * send your comments or suggestions to (info-gnuplot@dartmouth.edu).
  30.  *
  31.  * The 'postscript' driver produces landscape output 10" wide and 7" high.  
  32.  * To change font to Times-Roman and font size to 20pts use 
  33.  * 'set term postscript "Times-Roman" 20'.
  34.  * To get a smaller (5" x 3.5") eps output use 'set term post eps'
  35.  * and make only one plot per file.  Font size for eps will be half
  36.  * the specified size.
  37.  */
  38.  
  39.  
  40. /* PostScript driver by Russell Lang, rjl@monu1.cc.monash.edu.au */
  41.  
  42. char ps_font[MAX_ID_LEN+1] = "Helvetica" ; /* name of font */
  43. int ps_fontsize = 14;                     /* size of font in pts */
  44. TBOOLEAN ps_portrait = FALSE;                 /* vertical page */
  45. TBOOLEAN ps_color = FALSE;
  46. TBOOLEAN ps_solid = FALSE;           /*  use solid lines */
  47. TBOOLEAN ps_eps = FALSE;    /* Is this for an eps file? */
  48.             /* Added by Robert Davis <davis@ecn.purdue.edu> */
  49. int ps_page=0;            /* page count */
  50. int ps_path_count=0;     /* count of lines in path */
  51. int ps_ang=0;            /* text angle */
  52. enum JUSTIFY ps_justify=LEFT;    /* text is flush left */
  53.  
  54. char GPFAR * GPFAR PS_header[] = {
  55. "/M {moveto} bind def\n",
  56. "/L {lineto} bind def\n",
  57. "/R {rmoveto} bind def\n",
  58. "/V {rlineto} bind def\n",
  59. "/vpt2 vpt 2 mul def\n",
  60. "/hpt2 hpt 2 mul def\n",
  61. /* flush left show */
  62. "/Lshow { currentpoint stroke M\n",
  63. "  0 vshift R show } def\n", 
  64. /* flush right show */
  65. "/Rshow { currentpoint stroke M\n",
  66. "  dup stringwidth pop neg vshift R show } def\n", 
  67. /* centred show */
  68. "/Cshow { currentpoint stroke M\n",
  69. "  dup stringwidth pop -2 div vshift R show } def\n", 
  70. /* Dash or Color Line */
  71. "/DL { Color {setrgbcolor Solid {pop []} if 0 setdash }\n",
  72. " {pop pop pop Solid {pop []} if 0 setdash} ifelse } def\n",
  73. /* Border Lines */
  74. "/BL { stroke gnulinewidth 2 mul setlinewidth } def\n",
  75. /* Axes Lines */
  76. "/AL { stroke gnulinewidth 2 div setlinewidth } def\n",
  77. /* Plot Lines */
  78. "/PL { stroke gnulinewidth setlinewidth } def\n",
  79. /* Line Types */
  80. "/LTb { BL [] 0 0 0 DL } def\n", /* border */
  81. "/LTa { AL [1 dl 2 dl] 0 setdash 0 0 0 setrgbcolor } def\n", /* axes */
  82. "/LT0 { PL [] 0 1 0 DL } def\n",
  83. "/LT1 { PL [4 dl 2 dl] 0 0 1 DL } def\n",
  84. "/LT2 { PL [2 dl 3 dl] 1 0 0 DL } def\n",
  85. "/LT3 { PL [1 dl 1.5 dl] 1 0 1 DL } def\n",
  86. "/LT4 { PL [5 dl 2 dl 1 dl 2 dl] 0 1 1 DL } def\n",
  87. "/LT5 { PL [4 dl 3 dl 1 dl 3 dl] 1 1 0 DL } def\n",
  88. "/LT6 { PL [2 dl 2 dl 2 dl 4 dl] 0 0 0 DL } def\n",
  89. "/LT7 { PL [2 dl 2 dl 2 dl 2 dl 2 dl 4 dl] 1 0.3 0 DL } def\n",
  90. "/LT8 { PL [2 dl 2 dl 2 dl 2 dl 2 dl 2 dl 2 dl 4 dl] 0.5 0.5 0.5 DL } def\n",
  91. "/P { stroke [] 0 setdash\n", /* Point */
  92. "  currentlinewidth 2 div sub M\n",
  93. "  0 currentlinewidth V stroke } def\n",
  94. "/D { stroke [] 0 setdash 2 copy vpt add M\n", /* Diamond */
  95. "  hpt neg vpt neg V hpt vpt neg V\n",
  96. "  hpt vpt V hpt neg vpt V closepath stroke\n",
  97. "  P } def\n",
  98. "/A { stroke [] 0 setdash vpt sub M 0 vpt2 V\n", /* Plus (Add) */
  99. "  currentpoint stroke M\n",
  100. "  hpt neg vpt neg R hpt2 0 V stroke\n",
  101. "  } def\n",
  102. "/B { stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M\n", /* Box */
  103. "  0 vpt2 neg V hpt2 0 V 0 vpt2 V\n",
  104. "  hpt2 neg 0 V closepath stroke\n",
  105. "  P } def\n",
  106. "/C { stroke [] 0 setdash exch hpt sub exch vpt add M\n", /* Cross */
  107. "  hpt2 vpt2 neg V currentpoint stroke M\n",
  108. "  hpt2 neg 0 R hpt2 vpt2 V stroke } def\n",
  109. "/T { stroke [] 0 setdash 2 copy vpt 1.12 mul add M\n", /* Triangle */
  110. "  hpt neg vpt -1.62 mul V\n",
  111. "  hpt 2 mul 0 V\n",
  112. "  hpt neg vpt 1.62 mul V closepath stroke\n",
  113. "  P  } def\n",
  114. "/S { 2 copy A C} def\n", /* Star */
  115. NULL
  116. };
  117.  
  118. #define PS_XOFF    50    /* page offset in pts */
  119. #define PS_YOFF    50
  120.  
  121. #define PS_XMAX 7200
  122. #define PS_YMAX 5040
  123.  
  124. #define PS_XLAST (PS_XMAX - 1)
  125. #define PS_YLAST (PS_YMAX - 1)
  126.  
  127. #define PS_VTIC (PS_YMAX/80)
  128. #define PS_HTIC (PS_YMAX/80)
  129.  
  130. #define PS_SC (10)                /* scale is 1pt = 10 units */
  131. #define    PS_LW (0.5*PS_SC)        /* linewidth = 0.5 pts */
  132.  
  133. #define PS_VCHAR (14*PS_SC)        /* default is 14 point characters */
  134. #define PS_HCHAR (14*PS_SC*6/10)
  135.  
  136. int PS_pen_x, PS_pen_y;
  137. int PS_taken;
  138. int PS_linetype_last;
  139. TBOOLEAN PS_relative_ok;
  140.  
  141. PS_options()
  142. {
  143.     extern struct value *const_express();
  144.     extern double real();
  145.  
  146.     if (!END_OF_COMMAND) {
  147.         if (almost_equals(c_token,"p$ortrait")) {
  148.             ps_portrait=TRUE;
  149.              ps_eps=FALSE;
  150.             c_token++;
  151.         }
  152.         else if (almost_equals(c_token,"l$andscape")) {
  153.             ps_portrait=FALSE;
  154.              ps_eps=FALSE;
  155.             c_token++;
  156.         }
  157.          else if (almost_equals(c_token,"e$psf")) {
  158.              ps_portrait=TRUE;
  159.              ps_eps = TRUE;
  160.              c_token++;
  161.          }
  162.         else if (almost_equals(c_token,"d$efault")) {
  163.             ps_portrait=FALSE;
  164.              ps_eps=FALSE;
  165.             ps_color=FALSE;
  166.             strcpy(ps_font,"Helvetica");
  167.             ps_fontsize = 14;
  168.             term_tbl[term].v_char = (unsigned int)(ps_fontsize*PS_SC);
  169.             term_tbl[term].h_char = (unsigned int)(ps_fontsize*PS_SC*6/10);
  170.             c_token++;
  171.         }
  172.     }
  173.  
  174.     if (!END_OF_COMMAND) {
  175.         if (almost_equals(c_token,"m$onochrome")) {
  176.             ps_color=FALSE;
  177.             c_token++;
  178.         }
  179.         else if (almost_equals(c_token,"c$olor")) {
  180.             ps_color=TRUE;
  181.             c_token++;
  182.         }
  183.     }
  184.  
  185.     if (!END_OF_COMMAND) {
  186.         if (almost_equals(c_token,"s$olid")) {
  187.             ps_solid=TRUE;
  188.             c_token++;
  189.         }
  190.         else if (almost_equals(c_token,"d$ashed")) {
  191.             ps_solid=FALSE;
  192.             c_token++;
  193.         }
  194.     }
  195.  
  196.     if (!END_OF_COMMAND && isstring(c_token)) {
  197.         quote_str(ps_font,c_token);
  198.         c_token++;
  199.     }
  200.  
  201.     if (!END_OF_COMMAND) {
  202.         /* We have font size specified */
  203.         struct value a;
  204.         ps_fontsize = (int)real(const_express(&a));
  205.         term_tbl[term].v_char = (unsigned int)(ps_fontsize*PS_SC);
  206.         term_tbl[term].h_char = (unsigned int)(ps_fontsize*PS_SC*6/10);
  207.     }
  208.  
  209.     sprintf(term_options,"%s %s %s \"%s\" %d",
  210.         ps_eps ? "eps" : (ps_portrait ? "portrait" : "landscape"),
  211.         ps_color ? "color" : "monochrome",
  212.         ps_solid ? "solid" : "dashed",
  213.         ps_font,ps_fontsize);
  214. }
  215.  
  216.  
  217. PS_init()
  218. {
  219. static char GPFAR psi1[] = "%%%%Creator: gnuplot\n\
  220. %%%%DocumentFonts: %s\n\
  221. %%%%BoundingBox: %d %d ";
  222. static char GPFAR psi2[] = "%%%%EndComments\n\
  223. /gnudict 40 dict def\ngnudict begin\n\
  224. /Color %s def\n\
  225. /Solid %s def\n\
  226. /gnulinewidth %.3f def\n\
  227. /vshift %d def\n\
  228. /dl {%d mul} def\n\
  229. /hpt %.1f def\n\
  230. /vpt %.1f def\n";
  231.  
  232. struct termentry *t = &term_tbl[term];
  233. int i;
  234.     ps_page = 0;
  235.     if (!ps_eps)
  236.         fprintf(outfile,"%%!PS-Adobe-2.0\n");
  237.     else
  238.         fprintf(outfile,"%%!PS-Adobe-2.0 EPSF-2.0\n");
  239.     fprintf(outfile, psi1, ps_font, PS_XOFF, PS_YOFF);
  240.     if (ps_portrait)
  241.         fprintf(outfile,"%d %d\n", 
  242.             (int)(xsize*(ps_eps ? 0.5 : 1.0)*(PS_XMAX)/PS_SC+0.5+PS_XOFF), 
  243.             (int)(ysize*(ps_eps ? 0.5 : 1.0)*(PS_YMAX)/PS_SC+0.5+PS_YOFF) );
  244.     else 
  245.         fprintf(outfile,"%d %d\n", 
  246.             (int)(ysize*(ps_eps ? 0.5 : 1.0)*(PS_YMAX)/PS_SC+0.5+PS_XOFF), 
  247.             (int)(xsize*(ps_eps ? 0.5 : 1.0)*(PS_XMAX)/PS_SC+0.5+PS_YOFF) );
  248.     if (!ps_eps)
  249.         fprintf(outfile,"%%%%Pages: (atend)\n");
  250.     fprintf(outfile, psi2,
  251.         ps_color ? "true" : "false",
  252.         ps_solid ? "true" : "false",
  253.         PS_LW,            /* line width */
  254.          (int)(t->v_char)/(-3),    /* shift for vertical centring */
  255.         PS_SC,            /* dash length */
  256.         PS_HTIC/2.0,        /* half point width */
  257.         PS_VTIC/2.0);        /* half point height */
  258.  
  259.     for ( i=0; PS_header[i] != NULL; i++)
  260.         fprintf(outfile,"%s",PS_header[i]);
  261.     fprintf(outfile,"end\n%%%%EndProlog\n");
  262. }
  263.  
  264.  
  265. PS_graphics()
  266. {
  267. static char GPFAR psg1[] = "0 setgray\n/%s findfont %d scalefont setfont\nnewpath\n";
  268. struct termentry *t = &term_tbl[term];
  269.     ps_page++;
  270.     if (!ps_eps)
  271.         fprintf(outfile,"%%%%Page: %d %d\n",ps_page,ps_page);
  272.     fprintf(outfile,"gnudict begin\ngsave\n");
  273.     fprintf(outfile,"%d %d translate\n",PS_XOFF,PS_YOFF);
  274.     fprintf(outfile,"%.3f %.3f scale\n", (ps_eps ? 0.5 : 1.0)/PS_SC,
  275.                                          (ps_eps ? 0.5 : 1.0)/PS_SC);
  276.     if (!ps_portrait) {
  277.         fprintf(outfile,"90 rotate\n0 %d translate\n", (int)(-PS_YMAX*ysize));
  278.     }
  279.     fprintf(outfile, psg1, ps_font, (t->v_char) );
  280.     ps_path_count = 0;
  281.     PS_relative_ok = FALSE;
  282.     PS_pen_x = PS_pen_y = -4000;
  283.     PS_taken = 0;
  284.     PS_linetype_last = -1;
  285. }
  286.  
  287.  
  288. PS_text()
  289. {
  290.     ps_path_count = 0;
  291.     fprintf(outfile,"stroke\ngrestore\nend\nshowpage\n");
  292.     /* fprintf(stderr,"taken %d times\n",PS_taken); */
  293.     /* informational:  tells how many times it was "cheaper"
  294.        to do a relative moveto or lineto rather than an
  295.        absolute one */
  296. }
  297.  
  298.  
  299. PS_reset()
  300. {
  301.     fprintf(outfile,"%%%%Trailer\n");
  302.     if (!ps_eps)
  303.         fprintf(outfile,"%%%%Pages: %d\n",ps_page);
  304. }
  305.  
  306.  
  307. PS_linetype(linetype)
  308. int linetype;
  309. {
  310. char *line = "ba012345678"; 
  311.     linetype = (linetype % 9) + 2;
  312.     PS_relative_ok = FALSE;
  313.     if (PS_linetype_last == linetype) return(0);
  314.     PS_linetype_last = linetype;
  315.     fprintf(outfile,"LT%c\n", line[linetype]);
  316.     ps_path_count = 0;
  317. }
  318.  
  319.  
  320. PS_move(x,y)
  321. unsigned int x,y;
  322. {
  323.     int dx, dy;
  324.     char abso[20],rel[20];
  325.     dx = x - PS_pen_x;
  326.     dy = y - PS_pen_y;
  327.     /* can't cancel all null moves--need a move after stroke'ing */
  328.     if (dx==0 && dy==0 && PS_relative_ok)
  329.         return(0);
  330.     sprintf(abso, "%d %d M\n", x, y);
  331.     sprintf(rel, "%d %d R\n", dx, dy);
  332.     if (strlen(rel) < strlen(abso) && PS_relative_ok){
  333.         fputs(rel, outfile);
  334.         PS_taken++;
  335.     }else
  336.         fputs(abso, outfile);
  337.     PS_relative_ok = TRUE;
  338.     ps_path_count += 1;
  339.     PS_pen_x = x;
  340.     PS_pen_y = y;
  341. }
  342.  
  343. PS_vector(x,y)
  344. unsigned int x,y;
  345. {
  346.     int dx, dy;
  347.     char abso[20],rel[20];
  348.     dx = x - PS_pen_x;
  349.     dy = y - PS_pen_y;
  350.     if (dx==0 && dy==0) return(0);
  351.     sprintf(abso, "%d %d L\n", x, y);
  352.     sprintf(rel, "%d %d V\n", dx, dy);
  353.     if (strlen(rel) < strlen(abso) && PS_relative_ok){
  354.         fputs(rel, outfile);
  355.         PS_taken++;
  356.     }else
  357.         fputs(abso, outfile);
  358.     PS_relative_ok = TRUE;
  359.     ps_path_count += 1;
  360.     PS_pen_x = x;
  361.     PS_pen_y = y;
  362.     if (ps_path_count >= 400) {
  363.         fprintf(outfile,"currentpoint stroke M\n");
  364.         ps_path_count = 0;
  365.     }
  366. }
  367.  
  368.  
  369. PS_put_text(x,y,str)
  370. unsigned int x, y;
  371. char *str;
  372. {
  373. char ch;
  374.     if (!strlen(str)) return(0);
  375.     PS_move(x,y);
  376.     if (ps_ang != 0)
  377.         fprintf(outfile,"currentpoint gsave translate %d rotate 0 0 M\n"
  378.             ,ps_ang*90);
  379.     putc('(',outfile);
  380.     ch = *str++;
  381.     while(ch!='\0') {
  382.         if ( (ch=='(') || (ch==')') || (ch=='\\') )
  383.             putc('\\',outfile);
  384.         putc(ch,outfile);
  385.         ch = *str++;
  386.     }
  387.     switch(ps_justify) {
  388.         case LEFT : fprintf(outfile,") Lshow\n");
  389.             break;
  390.         case CENTRE : fprintf(outfile,") Cshow\n");
  391.             break;
  392.         case RIGHT : fprintf(outfile,") Rshow\n");
  393.             break;
  394.     }
  395.     if (ps_ang != 0)
  396.         fprintf(outfile,"grestore\n");
  397.     ps_path_count = 0;
  398.     PS_relative_ok = FALSE;
  399. }
  400.  
  401. int PS_text_angle(ang)
  402. int ang;
  403. {
  404.     ps_ang=ang;
  405.     return TRUE;
  406. }
  407.  
  408. int PS_justify_text(mode)
  409. enum JUSTIFY mode;
  410. {
  411.     ps_justify=mode;
  412.     return TRUE;
  413. }
  414.  
  415. /* postscript point routines */
  416. PS_point(x,y,number)
  417. int x,y;
  418. int number;
  419. {
  420. char *point = "PDABCTS";
  421.     number %= POINT_TYPES;
  422.      if (number < -1)
  423.         number = -1;        /* negative types are all 'dot' */
  424.     fprintf(outfile,"%d %d %c\n", x, y, point[number+1]);
  425.     PS_relative_ok = 0;
  426.     ps_path_count = 0;
  427.     PS_linetype_last = -1; /* force next linetype change */
  428. }
  429.  
  430.